// HSS.Forms.BusyDialog.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.html
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       BusyDialog.cs
// Author:     HSS\gbanta
// Created:    08/12/2010
// Modified:   12/24/2010
// ----------------------------------------------------------------------------
namespace HSS.Forms
{
	#region Using Directives
	using System;
	using System.Windows.Forms;
	#endregion

	#region BusyDialog
	/// <summary>
	/// Displays a form busy dialog.
	/// </summary>
	public partial class BusyDialog : System.Windows.Forms.Form
	{
		private object lockObject = new object();
		private bool autoLoop;
		private bool autoLooping;
		private bool allowCancel;
		private const int noncancelHeight = 112;
		private const int cancelableHeight = 140;

		/// <summary>
		/// Displays a form busy dialog
		/// </summary>
		/// <param name="message">The text to display</param>
		public BusyDialog(string message)
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			this.lblMessage.Text = message;
			this.CommonInitialization();
		}
		/// <summary>
		/// Displays a form busy dialog
		/// </summary>
		/// <param name="message">The text to display</param>
		/// <param name="autoLoop">Auto loop the progress bar once the dialog is shown</param>
		public BusyDialog(string message, bool autoLoop)
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			this.lblMessage.Text = message;
			this.autoLoop = autoLoop;
			this.CommonInitialization();
		}
		/// <summary>
		/// Displays a form busy dialog
		/// </summary>
		/// <param name="message">The text to display</param>
		/// <param name="autoLoop">Auto loop the progress bar once the dialog is shown</param>
		/// <param name="allowCancel">Indicate whether or not the busy window is cancelable</param>
		public BusyDialog(string message, bool autoLoop, bool allowCancel)
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			this.lblMessage.Text = message;
			this.autoLoop = autoLoop;
			this.allowCancel = allowCancel;
			this.CommonInitialization();
		}
		private void CommonInitialization()
		{
			if (this.allowCancel)
			{
				this.Height = cancelableHeight;
				this.btnCancel.Visible = true;
			}
			else
			{
				this.Height = noncancelHeight;
				this.btnCancel.Visible = false;
			}
		}
		/// <summary>
		/// Begin auto looping
		/// </summary>
		public void AutoLoop()
		{
			if (!this.autoLooping)
			{
				this.Cursor = Cursors.WaitCursor;
				System.Threading.Thread th = new System.Threading.Thread(this.AutoLoopAsync);
				th.IsBackground = true;
				th.Start();
			}
		}
		private void AutoLoopAsync()
		{
			try
			{
				this.autoLooping = true;
				while (this.autoLooping)
				{
					this.AutoReset();
					this.PerformStep();
					System.Threading.Thread.CurrentThread.Join(_autoLoopDelay);
				}
			}
			finally
			{
				this.autoLooping = false;
			}
		}
		private void AutoReset()
		{
			if (this.InvokeRequired)
			{
				this.BeginInvoke(new MethodInvoker(this.AutoReset));
				return;
			}
			if (this.ProgressBusyBar.Value == this.ProgressBusyBar.Maximum)
				this.ProgressBusyBar.Value = 0;
		}
		private void PerformStep()
		{
			if (this.InvokeRequired)
			{
				this.BeginInvoke(new MethodInvoker(this.PerformStep));
				return;
			}

			if (null != this.Handle)
				this.ProgressBusyBar.PerformStep();
		}
		private void ResetProgressBar()
		{
			if (this.InvokeRequired)
			{
				this.BeginInvoke(new MethodInvoker(this.ResetProgressBar));
				return;
			}

			this.ProgressBusyBar.Value = 0;
		}

		/// <summary>
		/// Increments the Progress Bar by Value specified by the Increment Property
		/// </summary>
		public void IncrementStatusBar()
		{
			if (this.InvokeRequired)
			{
				this.Invoke(new MethodInvoker(this.IncrementStatusBar));
				return;
			}

			this.ProgressBusyBar.PerformStep();
			this.ProgressBusyBar.Refresh();
		}
		/// <summary>
		/// The Maximun Value for the Progress Bar
		/// </summary>
		public int Maximum
		{
			get
			{
				lock (lockObject)
					return this.ProgressBusyBar.Maximum;
			}
			set
			{
				lock (lockObject)
					this.ProgressBusyBar.Maximum = value;
			}
		}
		/// <summary>
		/// The Value by which to Increment the Progress Bar Value
		/// </summary>
		public int Increment
		{
			get
			{
				lock (lockObject)
					return this.ProgressBusyBar.Step;
			}
			set
			{
				lock (lockObject)
					this.ProgressBusyBar.Step = value;
			}
		}
		/// <summary>
		/// The current value of the Progress Bar
		/// </summary>
		public int StatusBarValue
		{
			get
			{
				lock (lockObject)
					return this.ProgressBusyBar.Value;
			}
		}
		/// <summary>
		/// The number of milliseconds to sleep in between advancing the progress bar.
		/// </summary>
		public int AutoLoopDelay
		{
			get { return _autoLoopDelay; }
			set { _autoLoopDelay = value; }
		} int _autoLoopDelay = 500;

		private void BusyDialog_Shown(object sender, EventArgs e)
		{
			if (this.autoLoop)
				this.AutoLoop();
		}

		private void BusyDialog_FormClosing(object sender, FormClosingEventArgs e)
		{
			this.autoLooping = false;
		}

		private void btnCancel_Click(object sender, EventArgs e)
		{
			if (this.allowCancel)
				this.Close();
		}
	}
	#endregion
}